<?php
namespace App\Logic\MonthlyReportLT;

use App\Models\CustomerDelivery\CustomerDelivery;
use App\Models\CustomerDelivery\CustomerDeliveryDetail;
use App\Models\MonthlyReportLT\Ex\SalesEx;
use App\Models\MonthlyReportLT\Payment\PaymentCancelOrderDelivery;
use App\Models\MonthlyReportLT\Payment\PaymentOrder;
use App\Models\Product\ProductSku;
use App\Models\Rakuten\RakutenOrderItem;
use App\Models\MonthlyReportLT\Tmp\TmpSales;
use Illuminate\Support\Facades\DB;
class MatchDeliverySku
{
    /**
     * 6.记录标记已发货但状态异常的订单
     * @param $time
     * @return void
     */
    private static function _matchSalesEx($time){
        $date = date('Y-m-01',$time);
        $items = TmpSales::query()
            ->where('report_date',$date)
//            ->where('psku_id','<>',0)
            ->where('cancel_status',0)
            ->where('status','<>',1)
            ->get()
            ->toArray();
        $count = count($items);
        $n = 0;
        foreach ($items as $item){
            unset($item['id']);
            $flag = SalesEx::query()->create($item);
            if($flag) $n++;
        }
        echo $count .'---'. $n;
    }

    /**
     * 5.记录后台已标记取消，但实际已发货的订单
     * @param $time
     * @return void
     */
    private static function _matchSalesCancelAndDelivery($time){
        $date = date('Y-m-01',$time);
        $items = TmpSales::query()
            ->where('report_date',$date)
            ->where('psku_id','<>',0)
            ->where('cancel_status',1)
            ->selectRaw('order_id,psku_id,sum(quantity) as quantity')
            ->groupBy(['order_id','psku_id'])
            ->get();
        $count = count($items);
        $n = 0;
        foreach ($items as $item){
            $reCount1 = PaymentCancelOrderDelivery::query()
                ->where('report_date',$date)
                ->where('order_id',$item->order_id)
                ->where('psku_id',$item->psku_id)
                ->count();
            if($reCount1 > 0)continue;
            $deliveryDetail = CustomerDeliveryDetail::query()
                ->selectRaw('sum(ship_num) as quantity,delivery_type')
                ->where('order_no',$item->order_id)
                ->where('psku_id',$item->psku_id)
                ->groupBy('delivery_type')
                ->get();
            if($deliveryDetail->isNotEmpty()){
                $data = [
                    'report_date' => $date,
                    'order_id' => $item->order_id,
                    'psku_id' => $item->psku_id,
                    'quantity' => $item->quantity,
                ];
                $num = 0;
                foreach ($deliveryDetail as $detail){
                    $data[CustomerDelivery::$_deliveryTypeMatchField[$detail->delivery_type]] = $detail->quantity;
                    $num += $detail->quantity;
                }
                if($num > 0){
                    $re = PaymentCancelOrderDelivery::query()->create($data);
                    if($re) $n++;
                }
            }
            $reCount2 = PaymentCancelOrderDelivery::query()
                ->where('report_date',$date)
                ->where('order_id',$item->order_id)
                ->where('psku_id',$item->psku_id)
                ->count();
            if(!$reCount2){
                $th_order_id = TmpSales::query()
                    ->where('report_date',$date)
                    ->where('psku_id','<>',0)
                    ->where('cancel_status',1)
                    ->where('order_id',$item->order_id)
                    ->where('psku_id',$item->psku_id)
                    ->value('th_order_id');
                if($th_order_id){
                    $flag = PaymentCancelOrderDelivery::query()->create([
                        'report_date' => $date,
                        'order_id' => $item->order_id,
                        'psku_id' => $item->psku_id,
                        'quantity' => $item->quantity,
                        'fba_quantity' => $item->quantity,
                    ]);
                    if($flag) $n++;
                }
            }
        }
        echo $count .'---'. $n;
    }

    /**
     * 4.未取消订单未能匹配到发货单但有三方发货记录
     * @param $time
     * @return void
     */
    private static function _matchExSalesAndThDelivery($time){
        $date = date('Y-m-01',$time);
        $items = TmpSales::query()
            ->where('report_date',$date)
            ->where('quantity','>',0)
            ->where('status','<>',1)
            ->get();
        $count = count($items);
        $n = 0;
        $data = [];
        foreach ($items as $item){
            if(!$item->th_order_id)continue;
            $key = $item->order_id.'_'.$item->psku_id;
            if(!array_key_exists($key,$data)) {
                $data[$key] = $item->quantity;
            }else{
                $data[$key] += $item->quantity;
            }
        }
        $count2 = count($data);
        foreach($data as $key => $quantity){
            list($order_id,$psku_id) = explode('_',$key);
            TmpSales::query()
                ->where('report_date',$date)
                ->where('order_id',$order_id)
                ->where('psku_id',$psku_id)
                ->update(['status' => 1]);//恢复状态值1，表示：正常
            $re = PaymentOrder::query()
                ->where('report_date',$date)
                ->where('order_id',$order_id)
                ->where('psku_id',$psku_id)
                ->first();
            if(!$re){
                $re = PaymentOrder::query()->create([
                    'report_date' => $date,
                    'order_id' => $order_id,
                    'psku_id' => $psku_id,
                    'quantity' => $quantity,
                    'fba_quantity' => $quantity,
                ]);
                if($re)$n++;
            }else{
                $re->fba_quantity += $quantity;
                $flag = $re->save();
                if($flag)$n++;
            }
        }
        echo $count .'---'. $count2.'---'. $n;
    }

    /**
     * 3.重新匹配发货单
     * 将Sales状态异常的订单根据发货单汇总重新到PaymentOrder
     * @param $time
     * @return void
     */
    private static function _matchSalesAndDeliveryAgain($time){
        $date = date('Y-m-01',$time);
        $items = TmpSales::query()
            ->where('report_date',$date)
            ->where('status','<>',1)
            ->selectRaw('order_id,psku_id,sum(quantity) as quantity')
            ->groupBy(['order_id','psku_id'])
            ->get();
        $count = count($items);
        $n = 0;
        foreach ($items as $item){
            $deliveryDetail = CustomerDeliveryDetail::query()
                ->selectRaw('sum(ship_num) as quantity,delivery_type')
                ->where('order_no',$item->order_id)
                ->where('psku_id',$item->psku_id)
                ->groupBy('delivery_type')
                ->get();
            if($deliveryDetail->isEmpty()){
                continue;
            }else{
                $data = [
                    'report_date' => $date,
                    'order_id' => $item->order_id,
                    'psku_id' => $item->psku_id,
                    'quantity' => $item->quantity,
                ];
                $num = 0;
                foreach ($deliveryDetail as $detail){
                    $data[CustomerDelivery::$_deliveryTypeMatchField[$detail->delivery_type]] = $detail->quantity;
                    $num += $detail->quantity;
                }
                if($num < $item->quantity){
                    continue;
                }else{
                    TmpSales::query()
                        ->where('report_date',$date)
                        ->where('order_id',$item->order_id)
                        ->where('psku_id',$item->psku_id)
                        ->update(['status' => 1]);//恢复状态值1，表示：正常
                    $re = PaymentOrder::query()->create($data);
                    if($re) $n++;
                }
            }
        }
        echo $count .'---'. $n;
    }

    /**
     * 2.通过乐天API抓取的订单更新状态值异常的订单的SKU ID
     * @param $time
     * @return void
     */
    private static function _matchOrderItem($time){
        $date = date('Y-m-01',$time);
        $items = TmpSales::query()
            ->where('report_date',$date)
            ->where('status','<>',1)
            ->get();
        $count = count($items);
        $n = 0;
        foreach ($items as $item){
            $orderItemCount = RakutenOrderItem::query()
                ->where('order_id',$item->order_id)
                ->where('platform_sku',$item->sku)
                ->count();
            if($orderItemCount > 1){
                echo '大于1==='.$item->order_id.'-----'.$item->sku.PHP_EOL;
            }elseif($orderItemCount == 1){
                $orderItem = RakutenOrderItem::query()
                    ->where('order_id',$item->order_id)
                    ->where('platform_sku',$item->sku)
                    ->first();
                $pSkuId = ProductSku::getValueByCode(str_replace(["\r\n","\n","\r"],'',$orderItem->variant_id),'id');
                if(!$pSkuId){
                    $item->status = 4;//状态值4表示：在ERP未匹配到SKU ID
                    $item->save();
                }else{
                    if($pSkuId != $item->psku_id){
                        $item->psku_id = $pSkuId;
                        $item->save();
                    }
                }
            }else{
                echo '0==='.$item->order_id.'-----'.$item->sku.PHP_EOL;
            }
            $n++;
        }
        echo $count .'---'. $n;
    }

    /**
     * 1.匹配发货单
     * 将Sales根据发货单汇总到PaymentOrder
     * @param $time
     * @return void
     */
    private static function _matchSalesAndDelivery($time){
        $date = date('Y-m-01',$time);
        $items = TmpSales::query()
            ->where('report_date',$date)
            ->where('psku_id','<>',0)
            ->where('cancel_status',0)
            ->selectRaw('order_id,psku_id,sum(quantity) as quantity')
            ->groupBy(['order_id','psku_id'])
            ->get();
        $count = count($items);
        $n = 0;
        foreach ($items as $item){
            $deliveryDetail = CustomerDeliveryDetail::query()
                ->selectRaw('sum(ship_num) as quantity,delivery_type')
                ->where('order_no',$item->order_id)
                ->where('psku_id',$item->psku_id)
                ->groupBy('delivery_type')
                ->get();
            if($deliveryDetail->isEmpty()){
                TmpSales::query()
                    ->where('report_date',$date)
                    ->where('order_id',$item->order_id)
                    ->where('psku_id',$item->psku_id)
                    ->update(['status' => 2]);//状态值2表示：未匹配到发货单明细
            }else{
                $data = [
                    'report_date' => $date,
                    'order_id' => $item->order_id,
                    'psku_id' => $item->psku_id,
                    'quantity' => $item->quantity,
                ];
                $num = 0;
                foreach ($deliveryDetail as $detail){
                    $data[CustomerDelivery::$_deliveryTypeMatchField[$detail->delivery_type]] = $detail->quantity;
                    $num += $detail->quantity;
                }
                if($num < $item->quantity){
                    TmpSales::query()
                        ->where('report_date',$date)
                        ->where('order_id',$item->order_id)
                        ->where('psku_id',$item->psku_id)
                        ->update(['status' => 3]);//状态值3表示：发货单明细数量异常
                }else{
                    $re = PaymentOrder::query()->create($data);
                    if($re) $n++;
                }
            }
        }
        echo $count .'---'. $n;
    }

    public static function exe($func,$date)
    {
        if('null' == $date){
            $time = strtotime('midnight first day of -1 month');
        }else{
            $time = strtotime($date);
        }
        try{
            DB::beginTransaction();
            self::{$func}($time);
            DB::commit();
        }catch (\Exception $e){
            DB::rollBack();
            report($e);
        }
    }
}
